//
// 企微日志线程的断点
//

// 1. 条件日志可以 再组合 条件命令，用来做一些变量判断，分支处理，不用执行脚本回调函数。
// 	  就是在条件命令中，先把需要判断的参数，数据保存到变量中。然后在条件日志的时候，根据这个变量来是否输出日志。
//    可以在函数入口或者出口（目标地址）附近下多个条件日志，实现对变量的 true和false的不同输出。
// 2. X64dbg 执行的时候，遇到条件断点，会先执行日志，后执行命令。命令中可以打日志，可以msg弹框，可以修改参数的值。

// 经验：
// 1. 标签后面不能有空格等，只能是冒号
// 2. rtr 执行的时候会产生单步异常，导致脚本不能继续自动执行，需要手动执行。
// 3. 对于输出参数，如何是野指针，可以直接访问，也不会崩溃。所以不必用mem.valid
// 4. mem.valid有失败的时候，不可控，尽量不依赖这个函数，直接访问不会崩溃
// 5. arg.get(0)访问参数和[esp+4] 是一样，在任何调用约定的函数头和函数尾部都可以用，因为在所有约定的函数尾部正好调用栈和函数入口一样，stdcall的在最后的"ret n"下断点也行。
//	  因为会先执行断点处的脚本，再执行"ret n"这条指令。
// 6. 给API下断点，kernel32的函数尽量下到kernelbase.dll中。
// 7. 脚本的断点下了以后，后面的在脚本断点中间间隔的手动断点可能无法停下来。或者是在 rtr 过程中的断点无法停下来。需要测试。
//   如果是这样，可以采用在函数头尾分别下断点的方法。也可以尝试在需要断点下来的位置加msg弹框。
// 8. 所有脚本断点启动之前，如果有断点，可能导致脚本断点无法执行。
// 9. 禁用、启用、删除断点 bpd bpe bpc 这三个命令 的参数只能是地址，不能是断点的名字
// 10. 只要脚本执行过程中，遇到手动的断点，那么这个脚本后面无法自动运行。这导致SetBreakpointCommand不适合大范围使用。可以在需要断点的地方用msgbox，这样估计能继续执行脚本



// 给API下断点
// 标签的位置，lable的位置，冒号后面不能有空格，否则不识别这个标签

bp wxwork+2B675F, "My_GetQrcodeReq_L7_LogPathL4_2B675F Start"
//SetBreakpointCommand wxwork+2B675F,  "scriptcmd call cbForLogPathL4"
bplog wxwork+2B675F, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: LogPathL4 start , callAddr={[esp]}"
bpcnd wxwork+2B675F, "0"
labelset wxwork+2B675F , "LogPathL4_2B675F" 



bp wxwork+2B6826, "after GetQueue"
bplog wxwork+2B6826, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  My_LogPath4  GetQueued overlapped= [ebp-1c]={[ebp-1c]}"
bpcnd wxwork+2B6826, "0"


bp wxwork+2B6897, "before mid call"
bplog wxwork+2B6897, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  before My_LogPath4 Call mid log  = [[edi+20+24]+20] = {utf8([[edi+20+24]+20])}, Overlapped=edi={edi}"
bpcnd wxwork+2B6897, "0"
//SetBreakpointCondition wxwork+2B6897, "strstr(utf8([[edi+20+24]+20]),\"StartUploadFileTask\")"


// 可以用条件命令和条件日志两种方式实现  条件日志
bp wxwork+2B6899, "bpFor_LogPathL4_call_L4mid"
//SetBreakpointCommand wxwork+2B6899, "scriptcmd call cbForLogPathL4_call_L4mid"
labelset wxwork+2B6899 , "LogPathL4_call_L4mid_2B6899" 

// 每次断下来的条件
SetBreakpointCondition wxwork+2B6899, 0
// 日志和日志条件
bplog wxwork+2B6899, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: LogPathL4_call_L4mid call addr = {mod.rva([edi+18])}, callAddr={[esp]}"
SetBreakpointLogCondition wxwork+2B6899, "([edi+18] == (wxwork+2B72D0))"



bp wxwork+2B695A, "My_GetQrcodeReq_L7_LogPathL4_2B675F End"
bpcnd wxwork+2B695A, "0"
bplog wxwork+2B695A, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: LogPathL4 end  , callAddr={[esp]}"
labelset wxwork+2B695A , "LogPathL4_End_2B695A" 







bp wxwork+2B72D0, "My_LogPathL3 start"
bpcnd wxwork+2B72D0, "0"
bplog wxwork+2B72D0, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  My_LogPathL3Call Start log  = [[ [[esp+8]+20]+24]+20] = {utf8([[ [esp+8]+20+24]+20])}"
labelset wxwork+2B72D0 , "LogPathL3" 


bp wxwork+2B72F3
bpcnd wxwork+2B72F3, "0"
bplog wxwork+2B72F3, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: before My_LogPathL3Call My_MakeCallClass log=[[ecx+24]+20]={utf8([[ecx+24]+20])}"


bp wxwork+002B7321, "My_LogPathL3_Mid "
bpcnd wxwork+002B7321, "0"
bplog wxwork+002B7321, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL3_Mid_Call , callAddr={[esp]}"


bp wxwork+289069, ""
bpcnd wxwork+289069, "0"
bplog wxwork+289069, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL3_Mid_Call_JMP addr = {mod.rva([eax+8])} , callAddr={[esp]}"
SetBreakpointLogCondition wxwork+289069, "([eax+8] == (wxwork+281560))"
	

bp wxwork+2B7340 , "My_LogPathL3 End"
bpcnd wxwork+2B7340, "0"
bplog wxwork+2B7340 , "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL3 end  , callAddr={[esp]}"
labelset wxwork+2B7340  , "LogPathL3_End" 









bp wxwork+281560, "My_LogPathL2 start"
bpcnd wxwork+281560, "0"
bplog wxwork+281560, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL2 start , str={utf8([ecx+20])} log = {utf8([esp+20])}, callAddr={[esp]}"
labelset wxwork+281560 , "LogPathL2" 


bp wxwork+28157F, "My_LogPathL2_mID"
bpcnd wxwork+28157F, "0"
bplog wxwork+28157F, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL2_Mid , call addr={mod.rva([edx+8])} , parm5={(utf8([[esp+10]])},callAddr={[esp]}"
SetBreakpointLogCondition wxwork+28157F, "([edx+8] == (wxwork+2797D0))"
SetBreakpointCondition wxwork+28157F, "strstr(utf8([[esp+10]]),\"StartUploadFileTask\")"
	

bp wxwork+281582 , "My_LogPathL2 End"
bpcnd wxwork+281582, "0"
bplog wxwork+281582 , "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL2 end  , callAddr={[esp]}"
labelset wxwork+281582  , "LogPathL2_End" 








bp wxwork+2797D0, "My_LogPathL1 start"
bpcnd wxwork+2797D0, "0"
bplog wxwork+2797D0, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL1 start ,log = {utf8([[esp+14]])}, callAddr={[esp]}"
labelset wxwork+2797D0 , "LogPathL1_2797D0" 


bp wxwork+27980E, "My_LogPathL1_mID"
bpcnd wxwork+27980E, "0"
bplog wxwork+27980E, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL1_Mid , upload log = {utf8([[esp+14]])}, callAddr={[esp]}"
// 需要用反斜杠转义
SetBreakpointCondition wxwork+27980E, "strstr(utf8([[esp+14]]),\"StartUploadFileTask\")"


bp wxwork+2799CE , "My_LogPathL1 End"
bpcnd wxwork+2799CE, "0"
bplog wxwork+2799CE , "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: My_LogPathL1 end  , callAddr={[esp]}"
labelset wxwork+2799CE  , "LogPathL1_End" 





GetQueued_Start$ = KernelBase.GetQueuedCompletionStatus
bp GetQueued_Start$, "GetQueuedCompletionStatus Start"
bpcnd GetQueued_Start$ , "0"
bplogcondition GetQueued_Start$, "1"
bplog GetQueued_Start$, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  GetQueued start ... CmpPort={[esp+4]}，pNum={[esp+8]}，lpKey={[esp+c]}，lpOlpd={[esp+10]}，dwMilliseconds={[esp+14]}，callAddr={[esp]}"



// 左侧笔记本
// GetQueued_End$ = KernelBase+14473D
// 右侧台式机
GetQueued_End$ = KernelBase+145E3D
bp GetQueued_End$ , "GetQueuedCompletionStatus End"
bpcnd GetQueued_End$ , "0"
bplogcondition GetQueued_End$, "1"
bplog GetQueued_End$, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  GetQueued End ... *pNum={[arg.get(1)]}，*pCmpKey={[arg.get(2)]}，*lpOverlapped={[arg.get(3)]}，dwMilliseconds={arg.get(4)}，retValue={eax}"
labelset GetQueued_End$ , "GetQueuedCompletionStatus End"


CallPostQueueL1$ = wxwork+2789AA
bp CallPostQueueL1$, "CallPostQueueL1"
bpcnd CallPostQueueL1$ , "((tid()==AAB0)&&([EDI+14]==524))"
bplogcondition CallPostQueueL1$, "1"
bplog CallPostQueueL1$, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CallPostQueueL1 log  = [[ebx+20+24]+20] = {utf8([[ebx+20+24]+20])}, Overlapped=ebx={ebx}" 


PostQueued_Start$ = KernelBase.PostQueuedCompletionStatus
bp PostQueued_Start$, "PostQueuedCompletionStatus Start"
bpcnd PostQueued_Start$ , "0"
bplogcondition PostQueued_Start$, "1"
bplog PostQueued_Start$, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: PostQueued start ... CmpPort={arg.get(0)}，numTransfer={arg.get(1)}，dwCompletionKey={arg.get(2)}，lpOverlapped={arg.get(3)}，callAddr={[esp]}"




// 左侧笔记本
// PostQueuedCompletionStatus_End$ = KernelBase+143FB9 
// 右侧台式机
PostQueuedCompletionStatus_End$ = KernelBase+1456B9 
bp PostQueuedCompletionStatus_End$, "PostQueuedCompletionStatus End"
bpcnd PostQueuedCompletionStatus_End$ , "0"
bplogcondition PostQueuedCompletionStatus_End$, "1"
bplog PostQueuedCompletionStatus_End$, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: PostQueuedCompletionStatus End ... retValue={eax}"
labelset PostQueuedCompletionStatus_End$ , "PostQueuedCompletionStatus End"



CreateIoPort_Start$ = KernelBase.CreateIoCompletionPort
bp CreateIoPort_Start$, "CreateIoCompletionPort Start"
bpcnd CreateIoPort_Start$ , "0"
bplogcondition CreateIoPort_Start$, "1"
bplog CreateIoPort_Start$, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateIoCompletionPort start ... FileHandle={arg.get(0)}，ExistPort={arg.get(1)}，dwCmpKey={arg.get(2)}，NumOfThread={arg.get(3)}，callAddr={[esp]}"



CreateIoCompletionPort_End$ = KernelBase+145F85
bp CreateIoCompletionPort_End$, "CreateIoCompletionPort End"
bpcnd CreateIoCompletionPort_End$ , "0"
bplogcondition CreateIoCompletionPort_End$, "1"
bplog CreateIoCompletionPort_End$, "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateIoCompletionPort End ... retValue={eax}"
labelset CreateIoCompletionPort_End$ , "CreateIoCompletionPort End"



goto main 

cbForLogPathL4:
	 log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: cbForLogPathL4 Start  callAddr={[esp]}"
	 goto main
	 

cbForLogPathL4_call_L4mid:
	 log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: LogPathL4_call_L4mid   filePath={utf16(arg.get(0))}, parm2={arg.get(1)}, parm3={arg.get(2)}, callAddr={[esp]}"
	 goto main
	 
   
main:
	run
	
	
ret